/*	Copyright 2007 - Xavier Baro (xbaro@cvc.uab.cat)

	This file is part of eapmlib.

    Eapmlib is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or any 
	later version.

    Eapmlib is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __SAMPLESEVALUATOR_H__
#define __SAMPLESEVALUATOR_H__

#include "EvolutiveLib.h"
#include "Evaluator.h"
#include "SamplesSet.h"
#include "Classifier.h"

namespace Evolutive {

	//! Defines the error function
	enum EVOLUTIVELIB_API ERROR_FUNCTION {ERROR_MISSCLASS,ERROR_WEIGHTED,ERROR_QUADRATIC};

	//! Defines the threshold method
	enum EVOLUTIVELIB_API THR_METHOD {THR_ZERO_FIXED,THR_ADAPT_THR};

	//! Class to evaluate a certain feature over a set of samples
	class EVOLUTIVELIB_API CSamplesEvaluator : public CEvaluator
	{
		//! Methods
	public:
		//! Default constructor		
		CSamplesEvaluator(void);

		//! Default destructor
		virtual ~CSamplesEvaluator(void);

#ifdef USE_OPENCV
		//! Returns the score for the stored classifier
		double GetScore(void);	
		
		//! Returns the score for a given chromosome (from base class)
		virtual double GetScore(CChromosome *C);		

		//! Verify if a certain Chromosome is a valid solution (from base class)
		virtual bool IsValid(CChromosome *C);
		
		//! Returns the score for a given a classifier
		double GetScore(CClassifier *C);	

		//! Sets the Samples set object
		void SetSamplesSet(CSamplesSet *Samples);

		//! Sets the feature object
		void SetClassifierObject(CClassifier *Classifier);

		//! Sets a pointer to the weight distribution
		void SetSamplesWeight(double *Weights);

		//! Sets the error function
		void SetErrorFunction(ERROR_FUNCTION ErrFunc);

		//! Sets the threshold method
		void SetThrMethod(THR_METHOD Method);

		//! Obtains the threshold and polarity values for the last evaluation
		void GetLastThreshold(double &Thr,double &Polarity);
				
	protected:
		//! Find the best threshold and polarity values for the current data
		double FindBestThreshold(void);

		//! Evalue the error of the samples set
		double GetErrorValue(double Threshold, double Polarity);
			
#endif //USE_OPENCV

		//! Attributes
	protected:		

		//! Pointer to the classifier object
		CClassifier *m_ClassifierObj;

		//! Pointer to the samples set
		CSamplesSet *m_SamplesSet;

		//! Pointer to a weight distribution over the samples.
		double *m_SamplesWeight;

		//! Array to store the samples value
		double *m_SamplesValue;

		//! Array to store the samples normalization factor
		double *m_NormFac;

		//! Polarity value for the last evaluation
		double m_Polarity;

		//! Threshold value for the last evaluation
		double m_ThresholdValue;

		//! Error function
		ERROR_FUNCTION m_ErrorFunction;

		//! Threshold method
		THR_METHOD m_ThrMethod;
	};	
}

#endif // __SAMPLESEVALUATOR_H__
